package fanshe;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

public class Demo01 {
    public static void main(String[] args) throws Exception {
        /**
         * 获取类对象三种方法
         * @param args
         */

        //第一种方法
        Class clazz = Class.forName("fanshe.Person");

        //第二种方法
        Class clazz2 = Person.class;

        //第三种方法
        Person person = new Person();
        Class clazz3 = person.getClass();

        //通过方法名获取方法
        Method method = clazz.getMethod("hh");
        //创建该类对象
        Object o = clazz.newInstance();
        //调用该方法，里面参数是该类的对象
        method.invoke(o);

        //获取构造方法
        //获取无参 public 构造方法
        Constructor constructor = clazz.getConstructor();
        System.out.println(constructor);

        //获取无参 所有构造方法(包括private)
        Constructor declaredConstructor = clazz.getDeclaredConstructor();
        System.out.println(declaredConstructor);


        //获取所有 public 构造方法
        Constructor[] constructors = clazz.getConstructors();
        System.out.println(Arrays.toString(constructors));


        //获取所有构造(包括private)
        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
        System.out.println(Arrays.toString(declaredConstructors));


        //根据构造器创建对象,constructor是上面的无参public构造函数
        Object o1 = constructor.newInstance();


        //获取方法
        //1,获取一个符合参数的public 方法
        Method hh = clazz.getMethod("hh");
        Method qq = clazz.getMethod("qq", int.class);  //两个参数,第一个是方法名，第二个是 参数类型.class
        Method ee = clazz.getMethod("ee");//ee()是无参static方法

        hh.invoke(o);//相当于o.hh();  o是上面  Object o = clazz.newInstance();创建的
        qq.invoke(o, 88);
        ee.invoke(null); //静态方法执行，不需要对象

        //2,获取一个符合参数的方法,包括public 和 private 类型
        Method ww = clazz.getDeclaredMethod("ww");//ww（）是无参私有方法
        ww.setAccessible(true);//ww（）方法是无参私有方法，不加这一行代码直接执行下一行代码会报错
        //setAccessible(boolean flag)  暴力反射，可以把私有方法也改成可以访问的
        ww.invoke(o);


        //3，获取所有的public方法，包含父类的
        Method[] methods = clazz.getMethods();


        //4,获取该类的所有方法，包含private方法，但不获取父类的方法
        Method[] declaredMethods = clazz.getDeclaredMethods();


        //获取成员变量
        //1,获取指定名称的public成员变量 getField(String name)
        Field s = clazz.getField("s");
        System.out.println(s);

        //2,获取所有public成员变量
        Field[] fields = clazz.getFields();
        System.out.println(Arrays.toString(fields));

        //3,获取指定名称的成员变量，包括private类型
        Field name = clazz.getDeclaredField("name");
        Field age = clazz.getDeclaredField("age");
        System.out.println(name);
        System.out.println(age);

        //4,获取所有的成员变量，包括private;
        Field[] declaredFields = clazz.getDeclaredFields();
        System.out.println(Arrays.toString(declaredFields));
    }
}
